home *** CD-ROM | disk | FTP | other *** search
- /*
- * This code is pretty much the unix adt distribution ftp code
- * (mostly because I have no idea how to do it myself :-))
- */
-
- #include "adt.h"
-
- #include <exec/libraries.h>
- #include <dos/dosextens.h>
- #include <dos/dos.h>
- #include <clib/dos_protos.h>
- #include <libraries/mui.h>
- #include <clib/alib_protos.h>
-
- #include <stdio.h>
- #include <stdarg.h>
- #include <stdlib.h>
-
- #include <bsdsocket.h>
- #include <sys/time.h>
- #include <sys/param.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/ioctl.h>
-
- #include <sys/time.h>
-
- #include <netinet/in.h>
- #include <netinet/tcp.h>
- #include <arpa/ftp.h>
- #include <arpa/telnet.h>
-
- #include <string.h>
- #include <netdb.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <errno.h>
- #include <ios1.h>
- #include <ctype.h>
-
-
- #define NBBY 8 /* number of bits in a byte */
- #define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
- #define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
- #define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
- #define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
- #define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
-
- #ifndef MAXHOSTNAMELEN
- #define MAXHOSTNAMELEN 64
- #endif
-
- #undef BUFSIZ
- #define BUFSIZ 1024
-
- #define s_close(x) CloseSocket(x)
-
- int sgetc(int);
- char *ftp_connect(char *host, char *path);
- int ftp_getreply(int);
- int ftp_command(char *, ...);
- void ftp_lostpeer(void);
- int ftp_login(void);
- int ftp_get(char *name, LONG size, char *local);
- int ftp_initconn(void);
- int ftp_dataconn(void);
-
- int din, fin, fout;
- FILE *dout;
-
- BOOL connected = FALSE;
- int fdata=-1, pgrp, code;
- struct sockaddr_in myctladdr, data_addr;
-
- char *login, *hostname;
-
- extern APTR app, get_gauge;
-
- int sgetc(int sock)
- {
- unsigned char c;
- fd_set rd,ex;
- long flgs;
- int n;
-
- struct timeval t;
- t.tv_sec = 10L;
- t.tv_usec = 0;
-
- FD_ZERO(&rd);
- FD_ZERO(&ex);
-
- FD_SET(sock,&rd);
- FD_SET(sock,&ex);
- flgs = SIGBREAKF_CTRL_D;
-
- WaitSelect(16,&rd,0L,&ex,&t,&flgs);
-
- if (FD_ISSET(sock,&rd))
- { n = recv(sock, &c, 1, 0);
- if (n == 1)
- return c;
- else return -1;
- }
-
- else return -1;
- }
-
- char *ftp_connect(char *host, char *path)
- {
- struct sockaddr_in server;
- struct servent *sp;
- struct hostent *hp;
- LONG s, len;
-
- if (connected) {
- ftp_command("QUIT");
- if (fout)
- s_close(fout);
- fout = -1;
- connected = FALSE;
- fdata = -1;
- }
-
- sp = getservbyname("ftp", "tcp");
- if ((sp = getservbyname("ftp", "tcp")) == NULL)
- return("*This site does not support FTP/TCP");
- /* hp = gethostbyname(host); */
- if ((hp = gethostbyname(host)) == NULL)
- return("FTP can't connect : Unknown Host");
-
- bzero((char *)&server, sizeof(server));
- bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length);
- server.sin_family = hp->h_addrtype;
- server.sin_port = sp->s_port;
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s < 0)
- return(sys_errlist[errno]);
- if (connect(s, (struct sockaddr const *)&server, sizeof(server)) < 0)
- return(sys_errlist[errno]);
- len = sizeof(myctladdr);
- if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0)
- return(sys_errlist[errno]);
- fout = /*fdopen(s, "w")*/s;
- fin = /*fdopen(s, "r")*/s;
- /* if (fin == NULL || fout == NULL) {
- if (fin) fclose(fin);
- if (fout) fclose(fout);
- return(sys_errlist[errno]);
- } */
-
- /* connected it seems */
-
- connected = 1;
-
- if (ftp_getreply(0) > 2) {
- ftp_lostpeer();
- return("Remote protocol error, startup message wrong");
- }
- if (!ftp_login()) {
- ftp_lostpeer();
- return("Connection refused");
- }
-
- /* logged in it seems */
-
- if (ftp_command("TYPE I") != COMPLETE) {
- ftp_lostpeer();
- return("Remote host has closed the connection");
- }
- if (ftp_command("CWD %s", path) != COMPLETE) {
- char message[256];
- ftp_lostpeer();
- sprintf(message, "Could not CD to directory \"%s\"\n", path);
- return(message);
- }
- return(NULL);
- }
-
- int ftp_getreply(int expecteof)
- {
- int c, n;
- int dig;
- int ocode = 0, cont = 0;
-
- for (;;) {
- dig = n = code = 0;
- while ((c = sgetc(fin)) != '\n') {
- if (c == IAC) { /* Telnet? */
- switch(c = sgetc(fin)) {
- case WILL:
- case WONT: {
- char temp[20]; int x;
- c = sgetc(fin);
- x = sprintf(temp, "%c%c%c", IAC, DONT, c);
- send(fout, temp, x, NULL);
- break;
- }
-
- case DO:
- case DONT: {
- char temp[20]; int x;
- c = sgetc(fin);
- x = sprintf(temp, "%c%c%c", IAC, WONT, c);
- send(fout, temp, x, NULL);
- break;
- }
-
- default:
- break;
- }
- continue;
- }
- dig++;
- if (c == EOF) {
- if (expecteof) {
- code = 221;
- return(0);
- }
- ftp_lostpeer();
- code = 421;
- return(4);
- }
- if (dig < 4 && isdigit(c))
- code = code * 10 + (c - '0');
- if (dig == 4 && c == '-') {
- if (cont)
- code = 0;
- cont++;
- }
- if (n == 0)
- n = c;
- }
- if (cont && code != ocode) {
- if (ocode == 0)
- ocode = code;
- continue;
- }
- if (code == 421 || ocode == 421)
- ftp_lostpeer();
- return(n - '0');
- }
- }
-
- /* send an FTP command */
-
- int ftp_command(char *fmt, ...)
- {
- va_list args;
- char comm[256];
- int len;
-
- va_start(args, fmt);
- len = vsprintf(comm, fmt, args);
- strcpy(&comm[len], "\r\n");
- send(fout, comm, len+2, NULL);
- va_end(args);
- return ftp_getreply(!strncmp(fmt, "QUIT", 4));
- }
-
- void ftp_lostpeer()
- {
- if (connected) {
- if (fout >= 0) {
- shutdown(fout, 2);
- fout = -1;
- }
- if (fdata >= 0) {
- shutdown(fdata, 2);
- close(fdata);
- fdata = -1;
- }
- connected = 0;
- }
- }
-
-
- int ftp_login()
- {
- int n;
-
- hostname = getenv("HOSTNAME");
- login = getenv("USERNAME");
- n = ftp_command("USER ftp");
- if (n == CONTINUE)
- n = ftp_command("PASS %s@%s", login, hostname);
- if (n == CONTINUE)
- n = ftp_command("ACCT %s@%s", login, hostname);
- if (n == COMPLETE)
- return(1);
- return(0);
- }
-
- /* return 0 on success */
- int ftp_get(char *name, LONG size, char *local)
- {
- char *buffer;
- int bytes=0, d=0, c, retval=1;
- ULONG signal;
-
- if (ftp_initconn()) {
- code = -1;
- return(1);
- }
- if (ftp_command("RETR %s", name) != PRELIM)
- return(1);
- din = ftp_dataconn();
- if (din == NULL)
- goto abort;
- dout = fopen(local, "w");
- if (dout == NULL)
- goto abort;
- buffer = malloc(BUFSIZ);
- if (buffer == NULL)
- goto abort;
-
- set(get_gauge, MUIA_Gauge_Current, 0);
- set(get_gauge, MUIA_Gauge_InfoText, name);
- set(get_gauge, MUIA_Gauge_Max, size);
-
- DoMethod(app, MUIM_Application_Input, &signal);
- while ((c = recv(din, buffer, BUFSIZ, NULL)) > 0) {
- if ((d = write(fileno(dout), buffer, c)) != c) break;
- bytes += c;
- if (size != 0)
- set(get_gauge, MUIA_Gauge_Current, bytes);
- if(DoMethod(app, MUIM_Application_Input, &signal) == ID_GetAbort) {
- retval = 2;
- goto abort;
- }
- }
- if (d < c)
- set(get_gauge, MUIA_Gauge_InfoText, "Error Writing file");
-
- set(get_gauge, MUIA_Gauge_InfoText, NULL);
- free(buffer);
- fclose(dout);
- s_close(din);
- ftp_getreply(0);
- return(0);
-
- abort:
- code = -1;
- free(buffer);
- if (fdata >= 0) {
- close(fdata);
- fdata = -1;
- }
- if (din)
- s_close(din);
- if (dout)
- fclose(dout);
- return(retval);
- }
-
- int ftp_initconn()
- {
- register char *p, *a;
- int result;
- LONG len;
-
- data_addr = myctladdr;
- data_addr.sin_port = 0;
- if (fdata != -1)
- close(fdata);
- fdata = socket(AF_INET, SOCK_STREAM, 0);
- if (fdata < 0)
- return(1);
- if (bind(fdata, (struct sockaddr *)&data_addr, sizeof(data_addr)) < 0)
- goto bad;
- len = sizeof(data_addr);
- if (getsockname(fdata, (struct sockaddr *)&data_addr, &len) < 0)
- goto bad;
- listen(fdata, 1);
- a = (char *)&data_addr.sin_addr;
- p = (char *)&data_addr.sin_port;
-
- #define UC(b) (((int)b)&0xff)
-
- result = ftp_command("PORT %d,%d,%d,%d,%d,%d", UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
- return(result != COMPLETE);
-
- bad:
- close(fdata);
- fdata = -1;
- return(1);
- }
-
- int ftp_dataconn()
- {
- struct sockaddr_in from;
- int s;
- LONG fromlen = sizeof(from);
-
- s = accept(fdata, (struct sockaddr *)&from, &fromlen);
- if (s < 0) {
- s_close(fdata);
- fdata = -1;
- return(NULL);
- }
- s_close(fdata);
- fdata = s;
- return(fdata);
- }
-